﻿namespace Pp.Core.Extentions
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text.RegularExpressions;
    using Domain.Model;
    using Dto;
    using FluentNHibernate.MappingModel;
    using Globalization;
    using System.Web;

    public static class CommonExtention
    {
        public static string GetFullName(this UserSmallDto userDto)
        {
            if (userDto == null) return string.Empty;
            return (userDto.FirstName == null || userDto.LastName == null)
                       ? userDto.Username
                       : string.Format("{0} {1}", userDto.FirstName, userDto.LastName);
        }
        public static string GetFullName(this UserSmallDto userDto, string link)
        {
            return string.Format("<a href='/{0}/{1}'>{2}</a>", link, userDto.Username, userDto.GetFullName());
        }
        public static string ToLink(this string str, string link)
        {
            return string.Format("<a href='/{0}'>{1}</a>", link, str);
        }
        public static bool IsMyLike(this ProjectDto projectDto, string name)
        {
            return projectDto.Likes.Where(d => d.UserDetail.Username == name).Count() > 0;
        }
        public static bool IsMyLike(this UserDto userDto, string name)
        {
            return userDto.Likes.Where(d => d.UserDetail.Username == name).Count() > 0;
        }
        public static string ToNotification(this LikeDto likeDto, bool isMyProfile, bool theyWork)
        {
            if (theyWork)
            {
                if (likeDto.Type == LikeType.Profile)
                    return likeDto.UserDetail.GetFullName("Profile/Index") + "," + "profil" + (isMyProfile ? "ini" : "i") + " " + Res.Label_Liked;
                if (likeDto.Type == LikeType.Project)
                    return likeDto.UserDetail.GetFullName("Profile/Index") + "," + "proje".ToLink("Project/Detail/{0}".FormatWith(likeDto.ProjectId)) + (isMyProfile ? "ni" : "yi") + " beğendi";
            }
            else
            {
                if (likeDto.Type == LikeType.Profile)
                    return likeDto.Name.ToLink("Profile/Index/{0}".FormatWith(likeDto.Username)) + "'ın," + "profil".ToLink("Profile/Index/{0}".FormatWith(likeDto.Username)) + (isMyProfile ? "ini" : "i") + " beğendi" + (isMyProfile ? "n" : string.Empty);
                if (likeDto.Type == LikeType.Project)
                    return likeDto.Name.ToLink("Project/Detail/{0}".FormatWith(likeDto.ProjectId)) + "'ın," + "proje".ToLink("Project/Detail/{0}".FormatWith(likeDto.ProjectId)) + (isMyProfile ? "sini" : "yi") + " beğendi" + (isMyProfile ? "n" : string.Empty);

            }
            return "";
        }
        public static string ToNotification(this CommentDto commentDto, bool isMyProfile, bool theyWork)
        {
            if (theyWork)
            {
                return commentDto.WhoIs.GetFullName("Profile/Index") + "," + "proje".ToLink("Project/Detail/{0}".FormatWith(commentDto.ProjectId)) + (isMyProfile ? "ne" : "ye") + " yorum yaptı.";
            }
            return commentDto.WhoIs.GetFullName("Profile/Index") + "'ın," + "proje".ToLink("Project/Detail/{0}".FormatWith(commentDto.ProjectId)) + (isMyProfile ? "sine" : "ye") + " yorum yaptı" + (isMyProfile ? "n" : string.Empty);
        }
        public static IList<LikeDto> NottingShowed(this IList<LikeDto> likeDto)
        {
            return likeDto.Where(d => d.IsShowed == false).ToList();
        }
        public static string GetFullName(this User user)
        {
            if (user == null) return string.Empty;
            return (user.FirstName == null || user.LastName == null)
                       ? user.Username
                       : string.Format("{0} {1}", user.FirstName, user.LastName);
        }
        public static string ToSmallImageString(this Guid id, ImageType imageType)
        {
            if (imageType == ImageType.Profile)
                return "/Content/Upload/Avatar/" + id + ImageSize.small + ".jpg";
            if (imageType == ImageType.Project)
                return "/Content/Upload/Project/" + id + ImageSize.small + ".jpg";
            if (imageType == ImageType.ProjectCategory)
                return "/Content/Upload/ProjectCategory/" + id + ImageSize.small + ".jpg";
            if (imageType == ImageType.Angel)
                return "/Content/Upload/Angel/" + id + ImageSize.small + ".jpg";
            return "";
        }
        public static string ToMediumImageString(this Guid id, ImageType imageType)
        {
            if (imageType == ImageType.Profile)
                return "/Content/Upload/Avatar/" + id + ImageSize.medium + ".jpg";
            if (imageType == ImageType.Project)
                return "/Content/Upload/Project/" + id + ImageSize.medium + ".jpg";
            if (imageType == ImageType.ProjectCategory)
                return "/Content/Upload/ProjectCategory/" + id + ImageSize.medium + ".jpg";
            if (imageType == ImageType.Angel)
                return "/Content/Upload/Angel/" + id + ImageSize.medium + ".jpg";
            return "";
        }
        public static string ToLargeImageString(this Guid id, ImageType imageType)
        {
            if (imageType == ImageType.Profile)
                return "/Content/Upload/Avatar/" + id + ImageSize.large + ".jpg";
            if (imageType == ImageType.Project)
                return "/Content/Upload/Project/" + id + ImageSize.large + ".jpg";
            if (imageType == ImageType.ProjectCategory)
                return "/Content/Upload/ProjectCategory/" + id + ImageSize.large + ".jpg";
            if (imageType == ImageType.Angel)
                return "/Content/Upload/Angel/" + id + ImageSize.large + ".jpg";
            return "";
        }
        public static string ToCrop(this string str, int length)
        {
            if (string.IsNullOrEmpty(str)) return Res.Information_nofound_information_for_project;
            if (str.Length < length) return str;
            return str.Substring(0, length) + "...";
        }
        public static UserDto ToDto(this User user)
        {
            if (user == null) return new UserDto();
            return new UserDto
                       {
                           CvInfo = user.CvInfo,
                           WorkInfo = user.WorkInfo,
                           EducationalInfo = user.EducationalInfo,
                           FirstName = user.FirstName,
                           LastName = user.LastName,
                           MailAdress = user.MailAdress,
                           Picture = user.Id.ToLargeImageString(ImageType.Profile),
                           Id = user.Id,
                           Username = user.Username,
                           IsActive = user.IsActive,
                           CreateDate = user.CreateDate,
                           MailAdressVisible = user.MailAdressVisible,
                           BirtDay = user.BirthDay,
                           City = user.City,
                           Likes = new List<LikeDto>(),
                           MyFollows = new List<FollowDto>(),
                           ProfileFollowers = new List<ProfileFollowDto>()
                       };
        }

        public static ProfileFollowDto ToDto(this ProfileFollow follow)
        {
            return new ProfileFollowDto
            {
                IsActive = follow.IsPassive,
                Follower = follow.Follower.ToSmallDto(),
                User = follow.User.ToSmallDto(),
                Reason = follow.Reason
            };
        }
        public static ProjectFollowDto ToDto(this ProjectFollow follow)
        {
            return new ProjectFollowDto
            {
                IsActive = follow.IsPassive,
                Follower = follow.Follower.ToSmallDto(),
                Project = follow.Project.ToSmallDto(),
                Reason = follow.Reason
            };
        }
        public static FollowDto ToDto(this Follow follow)
        {
            return new FollowDto
            {
                IsActive = follow.IsPassive,
                Follower = follow.Follower.ToSmallDto(),
                Reason = follow.Reason
            };
        }

        public static IList<ProjectFollowDto> ToDto(this IList<ProjectFollow> follows)
        {
            return new List<ProjectFollowDto>(follows.Select(d => d.ToDto()));
        }
        public static IList<ProfileFollowDto> ToDto(this IList<ProfileFollow> follows)
        {
            return new List<ProfileFollowDto>(follows.Select(d => d.ToDto()));
        }
        public static IList<FollowDto> ToDto(this IList<Follow> follows)
        {
            return new List<FollowDto>(follows.Select(d => d.ToDto()));
        }
        public static UserSmallDto ToSmallDto(this User user)
        {
            if (user == null) return new UserDto();
            return new UserSmallDto
            {
                CvInfo = user.CvInfo,
                FirstName = user.FirstName,
                LastName = user.LastName,
                MailAdress = user.MailAdress,
                Picture = user.Id.ToSmallImageString(ImageType.Profile),
                Id = user.Id,
                Username = user.Username,
                IsActive = user.IsActive,
                CreateDate = user.CreateDate,
                EducationalInfo = user.EducationalInfo,
                MailAdressVisible = user.MailAdressVisible,
                WorkInfo = user.WorkInfo,
                BirtDay = user.BirthDay,
                City = user.City
            };
        }
        public static LikeDto ToDto(this Like like)
        {
            if (like == null) return new LikeDto();
            var likeDto = new LikeDto
            {
                UserDetail = like.Processor.ToSmallDto(),
                Id = like.Id,
                CreateDate = like.CreateDate,
                IsShowed = like.IsShowed
            };
            if (like is UserLike)
            {
                likeDto.Username = ((UserLike)like).User.Username;
                likeDto.Name = ((UserLike)like).User.GetFullName();
                likeDto.Type = LikeType.Profile;
            }
            if (like is ProjectLike)
            {
                likeDto.ProjectId = ((ProjectLike)like).Project.Id;
                likeDto.Name = ((ProjectLike)like).Project.Name;
                likeDto.Type = LikeType.Project;
            }
            return likeDto;
        }
        public static ProjectCategoryDto ToDto(this ProjectCategory category)
        {
            if (category == null) return new ProjectCategoryDto();
            return new ProjectCategoryDto
            {
                Category = category.Name,
                CategoryId = category.Id,
                ParentCategory = category.Parent == null ? string.Empty : category.Parent.Name,
                ParentCategoryId = category.Parent == null ? Guid.Empty : category.Parent.Id,
                Image = category.Id.ToMediumImageString(ImageType.ProjectCategory),
                ProjectCount = 0
            };
        }
        public static ProjectDto ToDto(this Project project)
        {
            if (project == null) return new ProjectDto();
            return new ProjectDto
                       {
                           Likes = project.Likes.ToDto(),
                           Description = project.Description,
                           SmallDescription = project.SmallDescription,
                           Name = project.Name,
                           Id = project.Id,
                           Image = project.Id.ToLargeImageString(ImageType.Project),
                           User = project.User.ToSmallDto(),
                           AllowAngelRequest = project.AllowAngelRequest,
                           AngelRequests = project.AngelRequests.ToDto(),
                           Category = project.Category.ToDto(),
                           Followers = project.Follows.ToDto(),
                           ProjectCost = project.ProjectCosting.GetValueOrDefault(),
                           SignatureCollect = project.SignatureCollect,
                           CreateDate = project.CreateDate
                       };
        }
        public static ProjectSmallDto ToSmallDto(this Project project)
        {
            if (project == null) return new ProjectSmallDto();
            return new ProjectSmallDto
            {
                Description = project.Description,
                SmallDescription = project.SmallDescription,
                Name = project.Name,
                Id = project.Id,
                Image = project.Id.ToLargeImageString(ImageType.Project),
                User = project.User.ToSmallDto(),
                AllowAngelRequest = project.AllowAngelRequest,
                Category = project.Category.ToDto(),
                SignatureCollect = project.SignatureCollect,
                CreateDate = project.CreateDate
            };
        }
        public static CommentDto ToDto(this Comment comment)
        {
            return new CommentDto
                       {
                           Comment = comment.CommentText,
                           CreateDate = comment.CreateDate,
                           WhoIs = comment.User.ToSmallDto(),
                           Id = comment.Id,
                           ProjectId = comment.Project.Id
                       };
        }
        public static IList<CommentDto> ToDto(this IList<Comment> comments)
        {
            return (from cmt in comments select cmt.ToDto()).OrderByDescending(d => d.CreateDate).ToList();
        }
        public static AngelDto ToDto(this Angel angel)
        {
            return new AngelDto
                       {
                           Name = angel.Name,
                           Description = angel.Description
                       };
        }
        public static AngelRequestDto ToDto(this AngelRequest angel)
        {
            AngelRequestStateDto state;
            Enum.TryParse(angel.State.ToString(), out state);
            return new AngelRequestDto
                       {
                           Id = angel.Id,
                           Project = angel.Project.ToSmallDto(),
                           User = angel.User.ToDto(),
                           State = state
                       };
        }
        public static IList<AngelDto> ToDto(this IList<Angel> angels)
        {
            return (from angel in angels select angel.ToDto()).OrderByDescending(d => d.Name).ToList();
        }
        public static IList<AngelRequestDto> ToDto(this IList<AngelRequest> angels)
        {
            return (from angel in angels select angel.ToDto()).ToList();
        }


        public static ProjectDetailDto ToDetailDto(this Project project)
        {
            if (project == null) throw new BussinessException(Res.Information_Project_cannot_come_null);
            var detail = new ProjectDetailDto
                             {
                                 Likes = project.Likes.ToDto(),
                                 Description = project.Description,
                                 SmallDescription = project.SmallDescription,
                                 Name = project.Name,
                                 Id = project.Id,
                                 Image = project.Id.ToLargeImageString(ImageType.Project),
                                 Category = project.Category.ToDto(),
                                 User = project.User.ToSmallDto(),
                                 Comments = project.Comments.ToDto(),
                                 Angels = project.Angels.ToDto(),
                                 AllowAngelRequest = project.AllowAngelRequest,
                                 AngelRequests = project.AngelRequests.ToDto(),
                                 Followers = project.Follows.ToDto(),
                                 ProjectCost = project.ProjectCosting.GetValueOrDefault(),
                                 SignatureCollect = project.SignatureCollect
                             };
            return detail;
        }
        public static ProjectEdit ToEditDto(this Project project)
        {
            if (project == null) throw new BussinessException(Res.Information_Project_cannot_come_null);
            var edit = new ProjectEdit
                           {
                               Description = project.Description,
                               Name = project.Name,
                               Id = project.Id,
                               Image = project.Id.ToLargeImageString(ImageType.Project),
                               CategoryId = project.Category.Id,
                               ProjectCosting = project.ProjectCosting,
                               AllowAllowRequest = project.AllowAngelRequest,
                               SmallDescription = project.SmallDescription,
                               SignatureCollect = project.SignatureCollect
                           };
            return edit;
        }
        public static string ToDefaultOrValue(this DateTime? dateTime)
        {
            return dateTime.HasValue ? dateTime.Value.ToShortDateString() : string.Empty;
        }

        public static IList<LikeDto> ToDto(this IList<Like> likes)
        {
            if (likes == null) return new List<LikeDto>();
            return (from like in likes
                    orderby like.CreateDate descending
                    select like.ToDto()).ToList();
        }
        public static IList<UserDto> ToDto(this IList<User> users)
        {
            if (users == null) return new List<UserDto>();
            return (from like in users
                    orderby like.CreateDate descending
                    select like.ToDto()).ToList();
        }
        public static PageList<UserDto> ToDto(this PageList<User> users)
        {
            if (users == null) return new PageList<UserDto>();
            return new PageList<UserDto>
                       {
                           List = (from like in users.List
                                   orderby like.CreateDate descending
                                   select like.ToDto()).ToList(),
                           PageInfo = users.PageInfo
                       };
        }
        public static IList<ProjectDto> ToDto(this IList<Project> projects)
        {
            if (projects == null) return new List<ProjectDto>();
            return (from project in projects
                    orderby project.CreateDate descending
                    select project.ToDto()).ToList();
        }
        public static IList<ProjectCategoryDto> ToDto(this IList<ProjectCategory> categories)
        {
            if (categories == null) return new List<ProjectCategoryDto>();
            return (from cat in categories
                    orderby cat.CreateDate descending
                    select cat.ToDto()).ToList();
        }
        public static IList<CommentDto> GetAllNotShowedComments(this IList<Project> projects)
        {
            var commentList = new List<CommentDto>();
            if (projects == null) return commentList;
            commentList.AddRange(projects.SelectMany(dto => dto.Comments.Where(d => d.IsShowed == false)).Select(pComment => pComment.ToDto()));
            return commentList;
        }
        public static bool CheckMail(this string mail)
        {
            var regex = new Regex(@"^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$");
            return regex.IsMatch(mail);
        }
        public static string ExistImage(this string str, HttpServerUtility server, ImageType type)
        {
            var local = server.MapPath(str);
            if (File.Exists(local))
                return str;
            return "/Content/Images/Default" + type + ".png";
        }
    }


}
